/**
 * 
 */
package org.vsg.stock.basic.service.volfigure;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import org.vsg.stock.basic.domain.VolFigureDetails;
import org.vsg.stock.basic.domain.VolFigureKlineDaily;
import org.vsg.stock.basic.domain.VolFigureKlineDailyPK;
import org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor;
import org.vsg.stock.core.domain.StockDailyKLine;
import org.vsg.stock.core.indicator.kline.ZigIndicatorResultItem;

/**
 *  处理缩量柱模式2，连续阴阳不齐，暗示调整在即
 *  
 * @author Bill Vison
 *
 */
public class DecreaseMod2Processor implements VolFigureKlineDailyProcessor {

	static private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	
	
	private Set<String> dailyKeys = new HashSet<String>();	
	
	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#processDailyData(java.util.List)
	 */
	@Override
	public List<VolFigureKlineDaily> processDailyData(
			List<StockDailyKLine> stkDailyKLineList) {

		List<VolFigureKlineDaily> klineDailyList = new Vector<VolFigureKlineDaily>();		
		
		double rate = 0.95;
		
		StockDailyKLine startLeveKline = null;
		double levelOpen = 0;
		for (int i = 0 ; i < stkDailyKLineList.size()-3 ; i++) {
			startLeveKline = stkDailyKLineList.get(i);
			levelOpen = startLeveKline.getOpen();
			
			StockDailyKLine tmpStartLeveKline = null;
			short status = 0;
			boolean fitMod2 = false;
			long lastTmpVol = 0;
			int continueLessAgainTimes = 0;
			for (int j = 1 ; j <= 3 ; j++) {
				tmpStartLeveKline = stkDailyKLineList.get( i+j );
				// --- break for out put ---
				if ( tmpStartLeveKline.getVol() >= startLeveKline.getVol() ) {
					fitMod2 = false;
					break;
				}
				if ( j == 3 ) {
					if ( tmpStartLeveKline.getClose() >= startLeveKline.getClose() ) {
						fitMod2 = false;
						break;
					}
				}
				
				if ( j == 1) {
					lastTmpVol = tmpStartLeveKline.getVol();
					if (tmpStartLeveKline.getYieldRate() > 0) {
						status = 1;
					} else if ( tmpStartLeveKline.getYieldRate() < 0 ) {
						status = -1;
					}
					continue;
				} 
				else if (j == 3) {
					StockDailyKLine lastDailyKline = stkDailyKLineList.get(i+j-1);
					// --- less than 0.05
					double compValue = Math.abs( (double)( tmpStartLeveKline.getVol() - lastDailyKline.getVol()) ) / lastDailyKline.getVol();

					if (compValue <= 0.05) {
						fitMod2 = false;
						break;						
					}
				}

				if ( tmpStartLeveKline.getVol() * rate > lastTmpVol ) {
					break;
				} else {
					
					// --- continue less account ---
					if ( lastTmpVol * rate >= tmpStartLeveKline.getVol() ) {
						++continueLessAgainTimes;
					}
					if (continueLessAgainTimes >= 2) {
						fitMod2 = false;
						break;						
					}


					lastTmpVol = tmpStartLeveKline.getVol();
				}
				
				
				if (
					(tmpStartLeveKline.getYieldRate() > 0 && status < 0 ) ||
					(tmpStartLeveKline.getYieldRate() < 0 && status > 0)
				) {
					// --- different ---
					fitMod2 = true;
				} 
			}

			
			if ( fitMod2) {

				String indexLine = startLeveKline.getId().getStockCode()+","+detail.getCode()+","+df.format( startLeveKline.getDate() );
				
				if (!dailyKeys.contains( indexLine) ) {
					// --- add to date for handle ---

					VolFigureKlineDailyPK idPk = new VolFigureKlineDailyPK();
					idPk.setCodeVolFigureDetails( this.detail.getCode() );
					idPk.setStockCode( startLeveKline.getId().getStockCode() );
					idPk.setStockStartDate( startLeveKline.getId().getDate() );

					// --- gen new data object ---
					VolFigureKlineDaily dailyInst = new VolFigureKlineDaily();
					dailyInst.setId( idPk );
					dailyInst.setStockDateEnd( stkDailyKLineList.get(i+3).getDate() );
					klineDailyList.add( dailyInst );
					
				}
				
				i +=3;
			}
			
		}
		

		return klineDailyList;
	}
	
	private List<ZigIndicatorResultItem> crests;

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setCrestsInCycle(java.util.List)
	 */
	@Override
	public void setCrestsInCycle(List<ZigIndicatorResultItem> crests) {
		this.crests = crests;

	}

	@Override
	public void setExistedVolFigureKineDaily(
			List<VolFigureKlineDaily> volFigureKlineDailyList) {
		// --- get the daily ---
		VolFigureKlineDailyPK id = null;
		for (VolFigureKlineDaily daily : volFigureKlineDailyList) {
			id = daily.getId();
			String keyLine = id.getStockCode()+ "," + id.getCodeVolFigureDetails()+"," + df.format( id.getStockStartDate() );
			dailyKeys.add( keyLine );
		}
		
	}

	private VolFigureDetails detail;	
	
	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setCurrentVolFigureDetails(org.vsg.stock.basic.domain.VolFigureDetails)
	 */
	@Override
	public void setCurrentVolFigureDetails(VolFigureDetails detail) {
		this.detail = detail;

	}

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setTroughsInCycle(java.util.List)
	 */
	@Override
	public void setTroughsInCycle(List<ZigIndicatorResultItem> troughs) {
		// TODO Auto-generated method stub

	}

}
